<?php

declare(strict_types=1);

namespace Plugin\Attractions\AttractionManagement\Service;

use App\Exception\BusinessException;
use App\Http\Common\ResultCode;
use Carbon\Carbon;
use Common\Common;
use DateTime;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Plugin\Attractions\AttractionManagement\Model\AttractionUser;
use Plugin\Attractions\AttractionManagement\Repository\AttractionInfoRepository;
use Plugin\Attractions\AttractionManagement\Repository\AttractionUserBookingRepository;
use Plugin\Attractions\AttractionManagement\Repository\AttractionUserRepository;
use Plugin\Attractions\AttractionManagement\Repository\AttractionUserTouristBookingRepository;
use Plugin\Attractions\AttractionManagement\Repository\AttractionUserTouristInfoRepository;

class BookingService
{
    #[Inject]
    protected AttractionUserBookingRepository $bookingRepository;

    #[Inject]
    protected AttractionUserTouristBookingRepository $touristBookingRepository;

    #[Inject()]
    protected AttractionUserRepository $userRepository;

    #[Inject()]
    protected AttractionInfoRepository $infoRepository;

    #[Inject]
    protected AttractionUserTouristInfoRepository $touristInfoRepository;

    // private function getBookingId(int $userId, $infoId): string
    // {
    //     $redis = Common::redis();
    //     $batch = $redis->get('booking:batch');
    //     if (!$batch) {
    //         $batch = 1;
    //         $serial = 1;
    //         $redis->set('booking:batch', $batch);
    //         $redis->set('booking:serial', $serial);
    //     }
    //     $serial = $redis->get('booking:serial');
    //     if ($serial > 9999) {
    //         $batch++;
    //         $serial = 1;
    //         $redis->set('booking:batch', $batch);
    //         $redis->set('booking:serial', $serial);
    //     }
    //     $time = date('Ymd', time());
    //     $id = sprintf('%d%s%04s', $batch, $time, $serial);
    //     $redis->incr('booking:serial');
    //     return $id;
    // }

    public function booking(array $data): array
    {
        $userId = $data['userId'];
        $infoId = intval($data['infoId']);
        // 检查用户是否存在
        if (!$this->userRepository->existsById($userId)) {
            throw new BusinessException(ResultCode::NOT_FOUND, trans('attraction-management.user.notFound'));
        }

        // 检查预约活动信息是否过期
        if (!$this->infoRepository->isValid($infoId)) {
            throw new BusinessException(ResultCode::NOT_FOUND, trans('attraction-management.info.notFound'));
        }

        Db::beginTransaction();
        try {
            // 创建预约订单
            $booking = $this->bookingRepository->create([
                // 'id' => $this->getBookingId($userId, $infoId),
                'user_id' => $userId,
                'info_id' => $infoId,
                'booking_day' => $data['bookingDay'],
                'booking_time' => $data['bookingTime'],
                'status' => 1, // 已预约
            ]);
            // 确保获取到自增主键
            $bookingId = is_object($booking) ? $booking->id ?? null : null;
            if (!$bookingId) {
                throw new BusinessException(ResultCode::FAIL, '预约订单创建失败');
            }
            // 如果有游客ID，关联游客信息
            if (isset($data['touristId'])) {
                $touristIds = explode(',', $data['touristId']);
                $insert = [];
                $touristIds = $this->touristInfoRepository->getQuery()->whereIn('id', $touristIds)
                    ->where('user_id', $userId)
                    ->pluck('id');
                foreach ($touristIds as $touristId) {
                    $insert[] = [
                        'booking_id' => $bookingId,
                        'tourist_id' => $touristId,
                    ];
                }
                if ($insert) {
                    $this->touristBookingRepository->getQuery()->insert($insert);
                }
            }
            Db::commit();
        } catch (\Throwable $e) {
            Db::rollBack();
            Common::logException(__CLASS__, $e);
            return [];
        }
        return ['id' => $booking->id];
    }

    public function bookingList(array $data): array
    {
        $map = [
            'userId' => $data['userId']
        ];
        if (isset($data['status'])) {
            $map['status'] = $data['status'];
        }
        return $this->bookingRepository
            ->showListPage($map);
    }

    public function updateStatus(array $data): int
    {
        return $this->bookingRepository->getQuery()
            ->whereIn('id', $data['id'])
            ->where('status', 1)
            ->where('user_id', $data['userId'])
            ->update(['status' => $data['status']]);
    }

    public function delete(array $data): int
    {
        $res = $this->bookingRepository->getQuery()
            ->where('user_id', $data['userId'])
            ->whereIn('id', $data['id'])
            ->delete();
        if (!$res) {
            return 0;
        }
        $this->touristBookingRepository->getQuery()
            ->whereIn('booking_id', $data['id'])
            ->delete();
        return $res;
    }
}
